// utils/request.js - 网络请求工具
const { apiBaseURL, timeout, cors } = require("../config/api.js");
const userStore = require("../store/userStore.js");
const { handleError, AUTH_TYPES } = require("./errorHandler.js");
const { handleApiResponse, isApiSuccess } = require("./apiErrorHandler.js");

/**
 * 检查是否需要登录
 * @param {number} statusCode HTTP状态码
 * @param {Object} response 响应数据
 * @returns {boolean} 是否需要登录
 */
const needLogin = (statusCode, response) => {
  // 401未授权或业务错误码表示需要登录
  return statusCode === 401 || (response && response.code === 401);
};

/**
 * 网络请求封装
 * @param {Object} options 请求参数
 * @param {string} options.url 请求路径
 * @param {string} options.method 请求方法 GET/POST/PUT/DELETE
 * @param {Object} options.data 请求数据
 * @param {Object} options.header 请求头
 * @param {boolean} options.showLoading 是否显示加载中
 * @param {string} options.loadingText 加载中文字
 */
const request = (options = {}) => {
  const {
    url,
    method = "GET",
    data = {},
    header = {},
    showLoading = true,
    loadingText = "加载中...",
    needAuth = true, // 是否需要认证
  } = options;

  // 显示加载中
  if (showLoading) {
    wx.showLoading({
      title: loadingText,
      mask: true,
    });
  }

  // 构建请求头
  const requestHeader = {
    "Content-Type": "application/json",
    // 跨域配置
    ...(cors.enabled && {
      "Access-Control-Allow-Origin": "*",
      "Access-Control-Allow-Methods": cors.methods.join(", "),
      "Access-Control-Allow-Headers": cors.headers.join(", "),
      "Access-Control-Allow-Credentials": cors.credentials.toString(),
    }),
    ...header,
  };

  // 如果需要认证且有token，添加Authorization头
  if (needAuth) {
    const token = userStore.getToken();
    if (token) {
      requestHeader.Authorization = token;
    }
  }

  return new Promise((resolve, reject) => {
    const makeRequest = () => {
      wx.request({
        url: apiBaseURL + url,
        method: method,
        data: data,
        header: requestHeader,
        timeout: timeout,
        success: async (res) => {
          wx.hideLoading();

          // 统一处理响应
          if (res.statusCode === 200) {
            if (isApiSuccess(res.data)) {
              resolve(res.data);
            } else if (needLogin(res.statusCode, res.data)) {
              // 需要登录，尝试自动登录
              if (needAuth) {
                try {
                  await userStore.wxLogin();
                  // 登录成功后重新发起请求
                  makeRequest();
                } catch (loginError) {
                  wx.hideLoading();
                  wx.showModal({
                    title: "提示",
                    content: "请先登录",
                    showCancel: false,
                    success: () => {
                      // 登录失败，可以跳转到个人中心页面
                      wx.switchTab({
                        url: "/pages/profile/profile",
                      });
                    },
                  });
                  reject(loginError);
                }
              } else {
                reject(res.data);
              }
            } else {
              // 业务错误处理
              wx.hideLoading();

              // 如果是需要授权的错误，尝试自动授权
              if (needLogin(res.statusCode, res.data) && needAuth) {
                try {
                  await userStore.wxLogin();
                  // 授权成功后重新发起请求
                  makeRequest();
                } catch (loginError) {
                  reject(res.data);
                }
              } else {
                // 直接返回原始错误数据，让调用方处理
                reject(res.data);
              }
            }
          } else {
            // HTTP错误
            wx.hideLoading();
            wx.showToast({
              title: "网络请求失败",
              icon: "none",
            });
            reject(res);
          }
        },
        fail: (err) => {
          wx.hideLoading();
          console.error("网络请求失败:", err);
          console.error("请求URL:", apiBaseURL + url);
          console.error("请求参数:", { method, data, header: requestHeader });

          // 根据错误类型显示不同的提示
          let errorMessage = "网络连接失败";
          if (err.errMsg) {
            if (err.errMsg.includes("timeout")) {
              errorMessage = "请求超时，请检查网络";
            } else if (err.errMsg.includes("fail")) {
              errorMessage = "网络请求失败，请检查网络连接";
            } else if (err.errMsg.includes("domain")) {
              errorMessage = "域名配置错误，请联系开发者";
            }
          }

          wx.showToast({
            title: errorMessage,
            icon: "none",
            duration: 3000,
          });
          reject(err);
        },
      });
    };

    makeRequest();
  });
};

/**
 * GET请求
 * @param {string} url 请求路径
 * @param {Object} data 请求参数
 * @param {Object} options 其他选项
 */
const get = (url, data = {}, options = {}) => {
  return request({
    url,
    method: "GET",
    data,
    ...options,
  });
};

/**
 * POST请求
 * @param {string} url 请求路径
 * @param {Object} data 请求数据
 * @param {Object} options 其他选项
 */
const post = (url, data = {}, options = {}) => {
  return request({
    url,
    method: "POST",
    data,
    ...options,
  });
};

/**
 * PUT请求
 * @param {string} url 请求路径
 * @param {Object} data 请求数据
 * @param {Object} options 其他选项
 */
const put = (url, data = {}, options = {}) => {
  return request({
    url,
    method: "PUT",
    data,
    ...options,
  });
};

/**
 * DELETE请求
 * @param {string} url 请求路径
 * @param {Object} data 请求参数
 * @param {Object} options 其他选项
 */
const del = (url, data = {}, options = {}) => {
  return request({
    url,
    method: "DELETE",
    data,
    ...options,
  });
};

/**
 * 无需认证的GET请求
 * @param {string} url 请求路径
 * @param {Object} data 请求参数
 * @param {Object} options 其他选项
 */
const getPublic = (url, data = {}, options = {}) => {
  return request({
    url,
    method: "GET",
    data,
    needAuth: false,
    ...options,
  });
};

/**
 * 无需认证的POST请求
 * @param {string} url 请求路径
 * @param {Object} data 请求数据
 * @param {Object} options 其他选项
 */
const postPublic = (url, data = {}, options = {}) => {
  return request({
    url,
    method: "POST",
    data,
    needAuth: false,
    ...options,
  });
};

/**
 * 检查网络状态
 * @returns {Promise<boolean>} 网络是否可用
 */
const checkNetworkStatus = () => {
  return new Promise((resolve) => {
    wx.getNetworkType({
      success: (res) => {
        console.log("网络类型:", res.networkType);
        if (res.networkType === "none") {
          wx.showToast({
            title: "网络不可用，请检查网络连接",
            icon: "none",
          });
          resolve(false);
        } else {
          resolve(true);
        }
      },
      fail: () => {
        wx.showToast({
          title: "无法获取网络状态",
          icon: "none",
        });
        resolve(false);
      },
    });
  });
};

module.exports = {
  request,
  get,
  post,
  put,
  delete: del,
  getPublic,
  postPublic,
  checkNetworkStatus,
};
